﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;

namespace WCFService
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            using (ServiceHost host = new ServiceHost(typeof(Caculator)))
            {
                host.Open();
                Console.WriteLine("Service begin");
                Console.WriteLine("press anykey to exist");
                Console.ReadKey();

            }
        }
    }

    [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICalculatorDuplexCallback))]
    public interface ICaculator
    {
        [OperationContract]
        int Add(int i, int j);

        [OperationContract]
        void RegeDit();

        [OperationContract]
        void UnkRegeDit();
    }


    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Caculator : ICaculator
    {
        public event AfterReadHandler OnAfterRead;

        public int Add(int i, int j)
        {
            int result = i + j;
            ICalculatorDuplexCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
            if (OnAfterRead != null)
            {
                OnAfterRead.BeginInvoke(result.ToString(), null, null);
            }
            return result;
        }

        public void RegeDit()
        {
            string key = OperationContext.Current.Channel.RemoteAddress.Uri.ToString();
            ICalculatorDuplexCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
            OnAfterRead += new AfterReadHandler(callback.ShowMessage);
            
        }

        public  void UnkRegeDit()
        {
            if (OnAfterRead != null)
            {
                OnAfterRead = null;
            }
        }
    }

    public interface ICalculatorDuplexCallback
    {
        [OperationContract(IsOneWay = true)]
        void ShowMessage(string msg);
    }

    public class CallbackEventArg : EventArgs
    {
        public CallbackEventArg(string parameter)
        {
            Parameter = parameter;
        }
        public string Parameter { get; internal set; }
    }

    public delegate void AfterReadHandler(string mark);


}
